package com.lili.core.hibernate.adapter.impl;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.lili.core.hibernate.adapter.IHibernateTemple;

public class HibernateTempleImpl extends HibernateDaoSupport implements
		IHibernateTemple {

	@Override
	public Object saveMergeObject(Object o) {
		return getHibernateTemplate().merge(o);
	}

	@Override
	public Serializable saveObject(Object o) {
		return getHibernateTemplate().save(o);

	}

	@Override
	public void removeObject(Class clazz, Serializable id) {
		getHibernateTemplate().delete(findById(clazz, id));
	}

	@Override
	public void removeObject(Object o) {
		getHibernateTemplate().delete(o);
	}

	@Override
	public void saveOrUpdateObject(Object o) {
		getHibernateTemplate().saveOrUpdate(o);

	}

	public void saveCollection(Collection entities) {
		getHibernateTemplate().saveOrUpdateAll(entities);
	}

	@Override
	public void delete(List objectList, int batchSize) {
		for (int i = 0; i < objectList.size(); i++) {
			this.removeObject(objectList.get(i));
			if (((i + 1) % batchSize) == 0) {
				this.getSession(false).flush();
				this.getSession(false).clear();
			}
		}

	}

	@Override
	public void update(List objects, int batchSize) {
		for (int i = 0; i < objects.size(); i++) {
			this.saveOrUpdateObject(objects.get(i));
			if (((i + 1) % batchSize) == 0) {
				this.getSession(false).flush();
				this.getSession(false).clear();
			}
		}

	}

	@Override
	public Object findListFirstObjectByHql(String hql) {
		List list = getHibernateTemplate().find(hql);
		if (list != null && list.size() > 0) {
			return list.get(0);
		}
		return null;
	}

	@Override
	public <T> T findById(Class<T> clazz, Serializable id) {
		return (T) getHibernateTemplate().get(clazz, id);
	}

	@Override
	public List findListByHql(String hql) {
		return getHibernateTemplate().find(hql);
	}

	@Override
	public Integer findCountByHql(final String countHql) {
		Object countObj = getHibernateTemplate().execute(
				new HibernateCallback() {
					@Override
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						return session.createQuery(countHql).uniqueResult();
					}
				});
		return Integer.getInteger(countObj.toString());

	}

	@Override
	public List getListForPage(final String hql, final int offset,
			final int pageSize) {
		List list = getHibernateTemplate().executeFind(new HibernateCallback() {
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query query = session.createQuery(hql);
				query.setFirstResult(offset);
				query.setMaxResults(pageSize);
				List list = query.list();
				return list;
			}
		});
		return list;
	}

}
